﻿using AutoMapper;
using NationalD3.Application.Interfaces;
using NationalD3.Application.ViewModels;
using NationalD3.Domain.Commands.Students;
using NationalD3.Domain.Entities;
using NationalD3.Domain.Interfaces;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NationalD3.Domain.Base;
using NationalD3.Application.EventSourcedNormalizers;

namespace NationalD3.Application.Services
{
    /// <summary>
    /// StudentAppService 服务接口实现类,继承 服务接口
    /// 通过 DTO 实现视图模型和领域模型的关系处理
    /// 作为调度者，协调领域层和基础层，
    /// 这里只是做一个面向用户用例的服务接口,不包含业务规则或者知识
    /// </summary>
    public class StudentAppService : IStudentAppService
    {
        //注意这里是要IoC依赖注入的，还没有实现
        private readonly IStudentRepository _StudentRepository;
        private readonly IEventStoreRepository _eventStoreRepository;

        //用来进行DTO
        private readonly IMapper _mapper;

        //中介者消息总线
        private readonly IEventBus _bus;
        // 事件源仓储
    
        public StudentAppService(IStudentRepository StudentRepository
                                , IMapper mapper
                                , IEventBus bus
                                , IEventStoreRepository eventStoreRepository)
        {
            _StudentRepository = StudentRepository;
            _eventStoreRepository = eventStoreRepository;
            _mapper = mapper;
            _bus = bus;
        }

        public IEnumerable<StudentViewModel> GetAll()
        {

            //第一种写法 Map
            return _mapper.Map<IEnumerable<StudentViewModel>>(_StudentRepository.GetAll());

            //第二种写法 ProjectTo
            //return (_StudentRepository.GetAll()).ProjectTo<StudentViewModel>(_mapper.ConfigurationProvider);
        }

        public StudentViewModel GetById(Guid id)
        {
            return _mapper.Map<StudentViewModel>(_StudentRepository.GetById(id));
        }

        /// <summary>
        /// 添加学生
        /// </summary>
        /// <param name="StudentViewModel"></param>
        public void Register(StudentViewModel StudentViewModel)
        {
            //自动将视图模型映射为命令模型
            var registerCommand = _mapper.Map<RegisterStudentCommand>(StudentViewModel);

            //发送命令消息
            _bus.SendCommand(registerCommand);

        }

        /// <summary>
        /// 修改学生
        /// </summary>
        /// <param name="StudentViewModel"></param>
        public void Update(StudentViewModel StudentViewModel)
        {
            var update = _mapper.Map<UpdateStudentCommand>(StudentViewModel);

            _bus.SendCommand(update);
        }

        /// <summary>
        /// 删除学生
        /// </summary>
        /// <param name="id"></param>
        public void Remove(Guid id)
        {
            _StudentRepository.Remove(id);
            _StudentRepository.SaveChanges();
        }

       
        /// <summary>
        /// 获取某一个聚合id下的所有事件，也就是得到了历史记录
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public IList<StudentHistoryData> GetAllHistory(Guid id)
        {
            var cha = _eventStoreRepository.All(id);
            return StudentHistory.ToJavaScriptStudentHistory(cha);
        }
        public void Dispose()
        {
            GC.SuppressFinalize(this);
        }

    }
}
